package com.iwhalecloud.bss.kite.cucc.service.pos.handler.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageInfo;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.ServiceOfferConsts;
import com.iwhalecloud.bss.kite.common.util.KiteBeanUtils;
import com.iwhalecloud.bss.kite.common.util.KiteDateUtils;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.reception.ICustReceptionService;
import com.iwhalecloud.bss.kite.cucc.client.dto.cust.CuccContextCustDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.order.KiteCustomerInfoReq;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosAttrDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosCustomerDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.scene.CuccCustInfoDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.scene.CuccCustInfoDetailDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.scene.CustAttrDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.CuccPosServiceUtils;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.IKitePosSceneHandler;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.KitePosHandlerContext;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;

@Service
public class KitePosCustomerHandler implements IKitePosSceneHandler {

    @Autowired
    private ICustReceptionService custReceptionService;

    @Autowired
    IQuerySceneInstService querySceneInstService;

    @Override
    public void handle(KitePosHandlerContext context) {
        CuccContextCustDTO custDto = context.getCustDto();
        KitePosCustomerDTO customer = new KitePosCustomerDTO();
        String sceneInstId = context.getSceneInstId();
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        KiteSceneInst kiteSceneInst = querySceneInstService.getSceneInst(context.getSceneInstId());
        String createDateStr = KiteDateUtils.formatDate(kiteSceneInst.getCreateDate(), KiteDateUtils.DATE_TIME_FORMAT_14);
        String cateId = CuccPosServiceUtils.getCateId(context.getSceneInstId(), context.getCustId());
        KiteOfferInst offerInst = CuccPosServiceUtils.getRootOfferInst(context.getSceneInstId(),
            context.getCustDto().getCustId());
        if (LocalServiceOfferConsts.SERVICE_OFFER_FOLLOW.equals(kiteSceneInst.getServiceOfferId())) {
            customer.setName(custDto.getCustName());
            customer.setCustType(custDto.getCustType());
            customer.setCustStatus("0");
            customer.setIsNewCustomer("0");
            customer.setAddress(custDto.getPostAddr());
            customer.setCbssId(custDto.getCustId());
            customer.setCustId(custDto.getBbssCustId());
            customer.setEparchyArea(custDto.getRegionId());
            customer.setEparchyProvince(custDto.getProvinceCode());
            customer.setGroupId(custDto.getGroupId());
        }
        else if (!KiteStringUtils.equalsAny(kiteSceneInst.getServiceOfferId(), ServiceOfferConsts.SERVICE_OFFER_TRANSFER, "1015")) {
            KiteBeanUtils.copyProperties(custDto, customer);
            customer.setName(custDto.getCustName());
            customer.setEparchyCity(Optional.ofNullable(custDto.getLanId()).orElse(custDto.getEparchyCode()));
            customer.setEparchyArea(custDto.getRegionId());
            customer.setEparchyProvince(custDto.getProvinceCode());
            customer.setCustType(custDto.getCustType());
            customer.setBssId(custDto.getBbssCustId());
            customer.setCbssId(custDto.getCustId());
            customer.setCustId(custDto.getBbssCustId());
            customer.setGroupId(custDto.getGroupId());
            // 云账号注册
            if (KiteStringUtils.equalsAny(cateId, "2000998", "2100982", "2100983")) {
                customer.setAddress(custDto.getPostAddr());
                customer.setContactName(custDto.getContactName());
                customer.setContactPhone(custDto.getContactPhone());
            }

            if (Objects.isNull(customer.getAttrs())) {
                customer.setAttrs(new ArrayList<>());
            }

            List<KitePosAttrDTO> custStateAttr = customer.getAttrs().stream().filter(attr -> KiteStringUtils.equals("custState", attr.getCode())).collect(Collectors.toList());
            if (KiteListUtils.isEmpty(custStateAttr)) {
                KitePosAttrDTO custState = new KitePosAttrDTO();
                custState.setCode("custState");
                custState.setValue("0");
                custState.setStartDate(createDateStr);
                custState.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
                customer.getAttrs().add(custState);
            }
            List<KitePosAttrDTO> certiTypeCodeAttr = customer.getAttrs().stream().filter(attr -> KiteStringUtils.equals("certiTypeCode", attr.getCode())).collect(Collectors.toList());
            if (KiteListUtils.isEmpty(certiTypeCodeAttr)) {
                KitePosAttrDTO certiTypeCode = new KitePosAttrDTO();
                certiTypeCode.setCode("certiTypeCode");
                certiTypeCode.setValue(Optional.ofNullable(custDto.getCertiTypeCode()).orElse(""));
                certiTypeCode.setStartDate(createDateStr);
                certiTypeCode.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
                customer.getAttrs().add(certiTypeCode);
            }
            List<KitePosAttrDTO> certiCodeAttr = customer.getAttrs().stream().filter(attr -> KiteStringUtils.equals("certiCode", attr.getCode())).collect(Collectors.toList());
            if (KiteListUtils.isEmpty(certiCodeAttr)) {
                KitePosAttrDTO certiCode = new KitePosAttrDTO();
                certiCode.setCode("certiCode");
                certiCode.setValue(Optional.ofNullable(custDto.getCertiCode()).orElse(""));
                certiCode.setStartDate(createDateStr);
                certiCode.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
                customer.getAttrs().add(certiCode);
            }
            if (KiteStringUtils.equalsAny(cateId, "2000998", "2100982", "2100983")) {
                List<KitePosAttrDTO> contactEmailAttr = customer.getAttrs().stream().filter(attr -> KiteStringUtils.equals("CONTACT_EMAIL", attr.getCode())).collect(Collectors.toList());
                if (KiteListUtils.isEmpty(contactEmailAttr)) {
                    KitePosAttrDTO contactEmail = new KitePosAttrDTO();
                    contactEmail.setCode("CONTACT_EMAIL");
                    contactEmail.setValue(Optional.ofNullable(custDto.getContactEmail()).orElse(""));
                    contactEmail.setStartDate(createDateStr);
                    contactEmail.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
                    customer.getAttrs().add(contactEmail);
                }
                List<KitePosAttrDTO> firstCallingTypeCodeAttr = customer.getAttrs().stream().filter(attr -> KiteStringUtils.equals("FIRST_CALLING_TYPE_CODE", attr.getCode())).collect(Collectors.toList());
                if (KiteListUtils.isEmpty(firstCallingTypeCodeAttr)) {
                    KitePosAttrDTO firstCallingTypeCode = new KitePosAttrDTO();
                    firstCallingTypeCode.setCode("FIRST_CALLING_TYPE_CODE");
                    firstCallingTypeCode.setValue(Optional.ofNullable(custDto.getFirstCallingTypeCode()).orElse(""));
                    firstCallingTypeCode.setStartDate(createDateStr);
                    firstCallingTypeCode.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
                    customer.getAttrs().add(firstCallingTypeCode);
                }
            }
        }
        else {
            //过户业务客户信息需要重新调整
            // 从缓存里面取
            Map<String, Object> extParameter = querySceneInstService.getExtParameter(sceneInstId);
            Object newCust = extParameter.get(sceneInstId + "_transNewCustDTO");
            CuccCustInfoDTO newCustDto = Objects.nonNull(newCust) ? (CuccCustInfoDTO) newCust : context.getNewCustDto();
            KiteBeanUtils.copyProperties(newCustDto, customer);
            // add by sqy 2020.10.8 属性对不上，转换不了，做特殊处理
            customer.setContactName(newCustDto.getAddress());
            customer.setEparchyCity(newCustDto.getEparchyCity());
            customer.setEparchyArea(newCustDto.getEparchyArea());
            customer.setName(newCustDto.getCustName());
            customer.setCustStatus(newCustDto.getCustState());
            customer.setCustType(newCustDto.getCustType());
            customer.setEparchyProvince(newCustDto.getProvinceCode());
            customer.setAddress(newCustDto.getAddr());
            customer.setBssId(newCustDto.getBbssCustId());
            customer.setCbssId(newCustDto.getCustId());
            customer.setCustId(newCustDto.getBbssCustId());
            customer.setContactName(newCustDto.getContactName());
            customer.setCustType(custDto.getCustType());
            customer.setGroupId(newCustDto.getGroupId());
            customer.setIsNewCustomer("0");
            List<KitePosAttrDTO> attrs = new ArrayList<>();

            KitePosAttrDTO custIDAttrs = new KitePosAttrDTO();
            CustAttrDTO custAttrDTOs = this.getAttrByCode(custDto, "custState");
            KiteBeanUtils.copyProperties(custAttrDTOs, custIDAttrs);
            custIDAttrs.setValue(newCustDto.getCustState());
            custIDAttrs.setCode("custState");
            attrs.add(custIDAttrs);

            List<CustAttrDTO> custAttrs = newCustDto.getAttrs();
            if (KiteListUtils.isNotEmpty(custAttrs)) {
                custAttrs.forEach(custAttr -> {
                    KitePosAttrDTO attr = new KitePosAttrDTO();
                    KiteBeanUtils.copyProperties(custAttr, attr);
                    attrs.add(attr);
                });
            }
            //证件类型
            KitePosAttrDTO certiTypeCodeAttr = new KitePosAttrDTO();
            CustAttrDTO certiTypeCodeAttrDTOs = this.getAttrByCode(custDto, "certiTypeCode");
            KiteBeanUtils.copyProperties(certiTypeCodeAttrDTOs, certiTypeCodeAttr);
            certiTypeCodeAttr.setValue(Optional.ofNullable(newCustDto.getCertiTypeCode()).orElse(""));
            certiTypeCodeAttr.setCode("certiTypeCode");
            attrs.add(certiTypeCodeAttr);
            //证件号码
            KitePosAttrDTO certiCodeAttr = new KitePosAttrDTO();
            CustAttrDTO certiCodeAttrDTOs = this.getAttrByCode(custDto, "certiCode");
            KiteBeanUtils.copyProperties(certiCodeAttrDTOs, certiCodeAttr);
            certiCodeAttr.setValue(Optional.ofNullable(newCustDto.getCertiCode()).orElse(""));
            certiCodeAttr.setCode("certiCode");
            attrs.add(certiCodeAttr);
            
            // 需要加原来老客户属性,补充isDefaultAcct属性节点
            // 从缓存里面取
            // 过户 目标账户板块 补充默认账户到属性节点（是否过默认账户  1：是；0：否）
            // String isDefaultAcct = querySceneInstService.getCommonAttrValue(sceneInstId, "isDefaultAcct");

            KitePosAttrDTO isDefaultAcctAttr = new KitePosAttrDTO();
            CustAttrDTO custAttrDTO = this.getAttrByCode(custDto, "isDefaultAcct");
            KiteBeanUtils.copyProperties(custAttrDTO, isDefaultAcctAttr);
            // 2021-12-22版本，过户，取消将默认账户转到新客户下的逻辑，此处传 0
            // isDefaultAcctAttr.setValue(isDefaultAcct);
            isDefaultAcctAttr.setValue("0");
            isDefaultAcctAttr.setCode("isDefaultAcct");
            attrs.add(isDefaultAcctAttr);
            //过户 用户名称变更板块 补充目标集团用户名称到属性节点
            String groupNewCustName = querySceneInstService.getCommonAttrValue(sceneInstId, "groupNewCustName");

            KitePosAttrDTO groupNewCustNameAttr = new KitePosAttrDTO();
            CustAttrDTO custAttrDTO1 = this.getAttrByCode(custDto, "groupNewCustName");
            KiteBeanUtils.copyProperties(custAttrDTO1, groupNewCustNameAttr);
            groupNewCustNameAttr.setValue(groupNewCustName);
            groupNewCustNameAttr.setCode("groupNewCustName");
            attrs.add(groupNewCustNameAttr);

            //过户 用户名称变更板块 补充原集团用户名称到属性节点
            String groupOldCustName = querySceneInstService.getCommonAttrValue(sceneInstId, "groupOldCustName");
            KitePosAttrDTO groupOldCustNameAttr = new KitePosAttrDTO();
            CustAttrDTO custAttrDTO2 = this.getAttrByCode(custDto, "groupOldCustName");
            KiteBeanUtils.copyProperties(custAttrDTO2, groupOldCustNameAttr);
            groupOldCustNameAttr.setValue(groupOldCustName);
            groupOldCustNameAttr.setCode("groupOldCustName");
            attrs.add(groupOldCustNameAttr);

            // 质检、重提时不需要重新取旧客户信息，因为custDto已经是新客户的客户信息了，只需重原始报文中的客户节点属性下取即可
            String taskCode = querySceneInstService.getExtParameterValue(sceneInstId, "taskCode");
            if (KiteStringUtils.equalsAny(taskCode, "OrderResubmit", "OrderSignedCheckSHZWY", "OrderResubmitZWY", "OrderResubmitXSWLW")) {
                List<KitePosAttrDTO> inputAttrs = context.getPosDto().getCustomer().getAttrs();
                attrs.addAll(inputAttrs.stream().filter(attr -> KiteStringUtils
                    .equalsAny(attr.getCode(), "oldCustId", "oldCbssId", "oldCustName", "oldCustState"
                        , "oldGroupId", "oldProvinceCode", "oldEparchyCode", "oldRegionId", "oldUserName", "oldUserLocation"))
                    .collect(Collectors.toList()));
            }
            else {
                this.dealOldCustInfo(attrs, custDto,sceneInstId);
            }
            customer.setAttrs(attrs);
        }
        //目前只有互联网传FirstCallingTypeCode，后续放开
        if(KiteStringUtils.isEmpty(DcPublicCache.getPCode("20211014145801",cateId))
            ||KiteStringUtils.isEmpty(DcPublicCache.getPCode("20211014145801",offerInst.getAttrValue("saleGoodsCode")))){
            customer.setFirstCallingTypeCode(null);
        }
        context.getPosDto().setCustomer(customer);
    }

    private CuccCustInfoDTO queryNewCustInfo(String custId) {
        KiteCustomerInfoReq kiteCustomerInfoReq = new KiteCustomerInfoReq();
        CuccCustInfoDTO cuccCustInfoDTO = new CuccCustInfoDTO();
        kiteCustomerInfoReq.setCustId(custId);
        String staffCode = ContextUtil.getSimpleLoginInfo().getStaffCode();
        String eparchyCode = ContextUtil.getSimpleLoginInfo().getLanId();
        String provinceCode = ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr();
        kiteCustomerInfoReq.setStaffCode(staffCode);
        kiteCustomerInfoReq.setEparchyCode(eparchyCode);
        kiteCustomerInfoReq.setProvinceCode(provinceCode);
        kiteCustomerInfoReq.setPageNum(1);
        kiteCustomerInfoReq.setPageSize(10);
        // 调用查询客户列表
        PageInfo<CuccCustInfoDTO> list = custReceptionService.customerListQueryNew(kiteCustomerInfoReq);
        if (!KiteObjectUtils.isEmpty(list) && KiteListUtils.isNotEmpty(list.getList())) {
            List<CuccCustInfoDTO> cuccCustInfoDTOList = list.getList();
            cuccCustInfoDTO = cuccCustInfoDTOList.get(0);
        }
        return cuccCustInfoDTO;
    }

    private void dealOldCustInfo(List<KitePosAttrDTO> attrs, CuccContextCustDTO custDto, String sceneInstId) {
        KitePosAttrDTO custIDAttr = new KitePosAttrDTO();
        CustAttrDTO custAttrDTO = this.getAttrByCode(custDto, "custId");
        KiteBeanUtils.copyProperties(custAttrDTO, custIDAttr);
        custIDAttr.setValue(custDto.getBbssCustId());
        custIDAttr.setCode("oldCustId");
        attrs.add(custIDAttr);

        KitePosAttrDTO cbssIdAttr = new KitePosAttrDTO();
        KiteBeanUtils.copyProperties(custAttrDTO, cbssIdAttr);
        cbssIdAttr.setValue(custDto.getCustId());
        cbssIdAttr.setCode("oldCbssId");
        attrs.add(cbssIdAttr);

        KitePosAttrDTO custNameAttr = new KitePosAttrDTO();
        custAttrDTO = this.getAttrByCode(custDto, "custName");
        KiteBeanUtils.copyProperties(custAttrDTO, custNameAttr);
        custNameAttr.setValue(custDto.getCustName());
        custNameAttr.setCode("oldCustName");
        attrs.add(custNameAttr);

        KitePosAttrDTO groupIdAttr = new KitePosAttrDTO();
        custAttrDTO = this.getAttrByCode(custDto, "groupId");
        KiteBeanUtils.copyProperties(custAttrDTO, groupIdAttr);
        groupIdAttr.setValue(custDto.getGroupId());
        groupIdAttr.setCode("oldGroupId");
        attrs.add(groupIdAttr);

        KitePosAttrDTO provinceCodeAttr = new KitePosAttrDTO();
        custAttrDTO = this.getAttrByCode(custDto, "provinceCode");
        KiteBeanUtils.copyProperties(custAttrDTO, provinceCodeAttr);
        provinceCodeAttr.setValue(custDto.getProvinceCode());
        provinceCodeAttr.setCode("oldProvinceCode");
        attrs.add(provinceCodeAttr);

        KitePosAttrDTO eparchyCodeAttr = new KitePosAttrDTO();
        custAttrDTO = this.getAttrByCode(custDto, "eparchyCode");
        KiteBeanUtils.copyProperties(custAttrDTO, eparchyCodeAttr);
        eparchyCodeAttr.setValue(custDto.getEparchyCode());
        eparchyCodeAttr.setCode("oldEparchyCode");
        attrs.add(eparchyCodeAttr);

        KitePosAttrDTO regionIdAttr = new KitePosAttrDTO();
        custAttrDTO = this.getAttrByCode(custDto, "regionId");
        KiteBeanUtils.copyProperties(custAttrDTO, regionIdAttr);
        regionIdAttr.setValue(custDto.getRegionId());
        regionIdAttr.setCode("oldRegionId");
        attrs.add(regionIdAttr);

        KitePosAttrDTO oldUserNameAttr = new KitePosAttrDTO();
        String oldUserName = querySceneInstService.getCommonAttrValue(sceneInstId, "group_user_name");
        oldUserNameAttr.setStartDate(KiteDateUtils.formatDate(new Date(), KiteDateUtils.DATE_TIME_FORMAT_14));
        oldUserNameAttr.setEndDate(KiteDateUtils.formatDate(new Date(), KiteDateUtils.DATE_TIME_FORMAT_14));
        oldUserNameAttr.setValue(oldUserName);
        oldUserNameAttr.setCode("oldUserName");
        attrs.add(oldUserNameAttr);

        String oldUserLocation = querySceneInstService.getExtParameterValue(sceneInstId, "oldUserLocation");
        KitePosAttrDTO oldUserLocationAttr = new KitePosAttrDTO();
        oldUserLocationAttr.setStartDate(KiteDateUtils.formatDate(new Date(), KiteDateUtils.DATE_TIME_FORMAT_14));
        oldUserLocationAttr.setEndDate(KiteDateUtils.formatDate(new Date(), KiteDateUtils.DATE_TIME_FORMAT_14));
        oldUserLocationAttr.setValue(oldUserLocation);
        oldUserLocationAttr.setCode("oldUserLocation");
        attrs.add(oldUserLocationAttr);

        KitePosAttrDTO custStateAttr = new KitePosAttrDTO();
        custAttrDTO = this.getAttrByCode(custDto, "custState");
        KiteBeanUtils.copyProperties(custAttrDTO, custStateAttr);
        if (KiteStringUtils.isNotEmpty(custDto.getCustStatus())) {
            custStateAttr.setValue(custDto.getCustStatus());
        }
        else {
            // 如果没有，再查一次客户列表接口获取客户状态
            CuccCustInfoDTO cuccCustInfoDTO = CuccPosServiceUtils.queryNewCustInfo(custDto.getCustId());
            if (Objects.nonNull(cuccCustInfoDTO)) {
                custStateAttr.setValue(cuccCustInfoDTO.getCustState());
            }
        }
        custStateAttr.setCode("oldCustState");
        attrs.add(custStateAttr);
    }

    private CustAttrDTO getAttrByCode(CuccContextCustDTO custDto, String code) {
        if (Objects.isNull(custDto.getAttrs())) {
            CustAttrDTO custAttr = new CustAttrDTO();
            custAttr.setCode(code);
            custAttr.setStartDate(KiteDateUtils.formatDate(new Date(), KiteDateUtils.DATE_TIME_FORMAT_14));
            custAttr.setEndDate(KiteDateUtils.formatDate(new Date(), KiteDateUtils.DATE_TIME_FORMAT_14));
            return custAttr;
        }
        List<CustAttrDTO> custAttrList = custDto.getAttrs().stream().filter(oldAttr -> "code".equals(oldAttr.getCode()))
            .collect(Collectors.toList());
        return KiteListUtils.isNotEmpty(custAttrList) ? custAttrList.get(0) : new CustAttrDTO();

    }

    private CuccCustInfoDetailDTO getCustInfo(String custId) {
        String staffCode = ContextUtil.getSimpleLoginInfo().getStaffCode();
        String eparchyCode = ContextUtil.getSimpleLoginInfo().getLanId();
        String provinceCode = ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr();
        KiteCustomerInfoReq kiteCustomerInfoReq = new KiteCustomerInfoReq();
        kiteCustomerInfoReq.setStaffCode(staffCode);
        kiteCustomerInfoReq.setEparchyCode(eparchyCode);
        kiteCustomerInfoReq.setProvinceCode(provinceCode);
        kiteCustomerInfoReq.setCustId(custId);
        CuccCustInfoDetailDTO cuccCustInfoDTO = custReceptionService.getCustomerDetail(kiteCustomerInfoReq)
            .getResultObject();
        if (Objects.isNull(cuccCustInfoDTO)) {
            ErrorConsts.BUSI_COMMON_ERROR.throwOut("提交订单失败，过户后的新客户信息不存在");
        }
        return cuccCustInfoDTO;
    }

}
